/*
 * Misc.h
 *
 *  Created on: 2011-7-7
 *      Author: gexiao
 */

#ifndef MISC_H_
#define MISC_H_
#include "Inlines.h"
#include "Common.h"
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>

/*
 * Floating point conversion functions.  These are necessary to avoid
 * strict-aliasing problems ("dereferencing type-punned pointer will break
 * strict-aliasing rules").  According to the gcc info page, this usage
 * is allowed, even with "-fstrict-aliasing".
 *
 * The code generated by gcc-4.1.1 appears to be much better than a
 * type cast dereference ("int foo = *(int*)&myfloat") when the conversion
 * function is inlined.  It also allows us to take advantage of the
 * optimizations that strict aliasing rules allow.
 */INLINE float dvmU4ToFloat(u4 val) {
	union {
		u4 in;
		float out;
	} conv;
	conv.in = val;
	return conv.out;
}
INLINE u4 dvmFloatToU4(float val) {
	union {
		float in;
		u4 out;
	} conv;
	conv.in = val;
	return conv.out;
}

/*
 * We pass one of these around when we want code to be able to write debug
 * info to either the log or to a file (or stdout/stderr).
 */
typedef struct DebugOutputTarget {
	//where to?
	enum {
		kDebugTargetUnknown = 0, kDebugTargetLog, kDebugTargetFile,
	} which;

	//additional bits
	union {
		struct {
			int priority;
			const char* tag;
		} log;
		struct {
			FILE* fp;
		} file;
	} data;
} DebugOutputTarget;

/*
 * Fill in a DebugOutputTarget struct.
 */
void dvmCreateLogOutputTarget(DebugOutputTarget* target, int priority,
		const char* tag);

/*
 * Print a debug message.
 */
void dvmPrintDebugMessage(const DebugOutputTarget* target, const char* format,
		...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 2, 3)))
#endif
;

/*
 * Expanding bitmap,used for tracking resources. Bits are numbered starting
 * from zero.
 */
typedef struct BitVector {
	bool expandable; //expand bitmap if we run out?
	int storageSize; //current size, in 32-bit words
	u4* storage;
} BitVector;

//allocate a bit vector with enough space to hold "startBits" bits
BitVector* dvmAllocBitVector(int startBits, bool expandable);
void dvmFreeBitVector(BitVector* pBits);
/*
 *
 */
int dvmAllocBit(BitVector* pBits);
void dvmClearBit(BitVector* pBits, int num);
/*
 *
 */
char* dvmDescriptorToDot(const char* str);

/*
 * Get the current time, in milliseconds.  This is "relative" time,
 * meaning it could be wall-clock time or a monotonic counter, and is
 * only suitable for computing time deltas.  The value returned from
 * this function is a u4 and should only be used for debugging
 * messages.  TODO: make this value relative to the start-up time of
 * the VM.
 */
INLINE u4 dvmGetRelativeTimeMsec(void) {

}

/*
 *
 */INLINE u8 dvmGetRelativeTimeUsec(void) {
}

/*
 * Sleep for increasingly longer periods, until "maxTotalSleep" microseconds
 * have elapsed.  Pass in the start time, which must be a value returned by
 * dvmGetRelativeTimeUsec().
 *
 * Returns "false" if we were unable to sleep because our time is up.
 */bool dvmIterativeSleep(int iteration, int maxTotalSleep, u8 relStartTime);

/*
 * Set the "close on exec" flag on a file descriptor.
 */bool dvmSetCloseOnExec(int fd);

/*
 * Unconditionally abort the entire VM. Try not to use this.
 */
void dvmAbort(void);

/*
 * Returns the pointer to the "absolute path" part of the given path
 * string, treating first (if any) instance of "/./" as a sentinel
 * indicating the start of the absolute path. If the path isn't absolute
 * in the usual way (i.e., starts with "/") and doesn't have the sentinel,
 * then this returns NULL.
 *
 * For example:
 *     "/foo/bar/baz" returns "/foo/bar/baz"
 *     "foo/./bar/baz" returns "/bar/baz"
 *     "foo/bar/baz" returns NULL
 *
 * The sentinel is used specifically to aid in cross-optimization, where
 * a host is processing dex files in a build tree, and where we don't want
 * the build tree's directory structure to be baked into the output (such
 * as, for example, in the dependency paths of optimized dex files).
 */
const char* dvmPathToAbsolutePortion(const char* path);
#endif /* MISC_H_ */
